<?php
/**
 * 原型模式
 * 
 */
spl_autoload_register('autoload');

function autoload($class) 
{
    require dirname($_SERVER['SCRIPT_FILENAME']) . '//..//' . str_replace('\\', '/', $class) . '.php';
}

/*============================= 测试 =============================*/
use prototype\MoneyPrototype;

$money = new MoneyPrototype();
$money->_name = "100元人民币";
$money->_faceValue = 100;
$money->_bankName = "中国人民银行";

//开始印钞
$money2 = $money->clone();
echo $money2->_name, "\n";
//echo "克隆了一张钞票：".$money2;

//第二种克隆方式：不需要->clone()方法
$money->_name = "1000元人民币"; //修改属性值再克隆 试试
$money->_faceValue = 1000;
$money3 = clone $money; 
echo $money3->_name, "\n";
echo $money2->_name, "\n"; //之前克隆的不受影响

/*
小结：
原型模式的应用场景：
一个对象多个修改者的场景
适用于大对象的创建

优点：
不用重新实例化来产生一个对象，而是直接拷贝一个对象在内存中运行时的状态，减少了new的开销，
既隐藏了对象的创建细节，又大大提高了性能。

缺点：
clone时，原型类的构造函数不会再调用，如果构造函数有约束条件，则跳过了。

与工厂模式的区别：
1.原型模式与工厂模式作用类似，都是用来创建对象
2.与工厂模式的实现不同，原型模式是先创建好一个原型对象，然后通过clone原型对象来创建新的对象，
  这样就免去了类创建时重复的初始化操作

注意：
clone对象后，只是做了浅拷贝
浅拷贝：就是值类型的全拷贝，引用类型的数据只拷贝一个地址
深拷贝：把引用类型的变量拷贝成一个新的对象（大话设计模式P87）
*/
